home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / oldwish / whence.c < prev    next >
C/C++ Source or Header  |  1990-01-19  |  3KB  |  163 lines

  1. # include    <stdio.h>
  2. # include    <ctype.h>
  3. # include    <sys/param.h>
  4. # include    <sys/stat.h>
  5. # include    <strings.h>
  6.  
  7. extern    char    *getenv();
  8.  
  9. static    char    *NextPart();    /* next name in the PATH */
  10.  
  11. static    char    privatefullpath[MAXPATHLEN];
  12.  
  13. /*
  14.  *---------------------------------------------------------------------
  15.  *
  16.  * Whence --
  17.  *
  18.  *    Using argv[0], figure out from where this program was called.
  19.  *    Copy the answer to a safe place and return a ptr to the answer.
  20.  *
  21.  * Results:
  22.  *    A pointer to the pathname of the directory whence this program was
  23.  *    called.  NULL if we aren't successful.
  24.  *
  25.  * Side effects:
  26.  *    None.
  27.  *
  28.  *---------------------------------------------------------------------
  29.  */
  30. char *
  31. Whence(fullpath, argv_zero)
  32. char    *fullpath;    /* must be MAXPATHLEN long or NULL */
  33. char    *argv_zero;    /* argv[0] passed in. */
  34. {
  35.     char    *p, *q;
  36.     char    *last_slash;
  37.     char    *path;
  38.     char    *argv0;
  39.     int        status1, status2;
  40.     int        found = 0;
  41.  
  42.     if (fullpath == NULL) {
  43.     fullpath = privatefullpath;
  44.     }
  45.     argv0 = argv_zero;
  46.     path = getenv("PATH");
  47.     if (argv0 == NULL || path == NULL || *argv0 == '\0' || *path == '\0') {
  48.     fullpath[0] = '\0';
  49.     return NULL;
  50.     }
  51.     if (*argv0 == '/') {
  52.     (void) strcpy(fullpath, argv0);
  53.     } else {
  54.     for (p = path, q = NextPart(&p, argv0, fullpath); q != NULL;
  55.         q = NextPart(&p, argv0, fullpath)) {
  56.         if ((status1 = is_a_file(q)) && (status2 = is_executable(q))) {
  57.         found = 1;
  58.         break;
  59.         } else if (status2 == -1) {
  60.         fullpath[0] = '\0';
  61.         return NULL;
  62.         }
  63.     }
  64.     if (!found) {
  65.         fullpath[0] = '\0';
  66.         return NULL;
  67.     }
  68.     }
  69.     if ((last_slash = rindex(fullpath, '/')) != NULL) {
  70.     *(last_slash) = '\0';
  71.     }
  72.  
  73.     return fullpath;
  74. }
  75.  
  76. static    char    name_buf[MAXPATHLEN];
  77. static    struct    stat    stat_buf;
  78.  
  79. int
  80. is_a_file(name)
  81. char    *name;
  82. {
  83.     if (strcmp(name_buf, name) != 0) {
  84.     (void) strcpy(name_buf, name);
  85.     if (stat(name, &stat_buf) != 0) {
  86.         return 0;
  87.     }
  88.     }
  89.     
  90.     if ((stat_buf.st_mode & S_IFMT) == S_IFREG) {
  91.     return 1;
  92.     }
  93.     return 0;
  94. }
  95.  
  96. int
  97. is_executable(name)
  98. char    *name;
  99. {
  100.     if (strcmp(name_buf, name) != 0) {
  101.     (void) strcpy(name_buf, name);
  102.     if (stat(name, &stat_buf) != 0) {
  103.         return -1;
  104.     }
  105.     }
  106.     
  107.     if ((stat_buf.st_mode & S_IEXEC) == S_IEXEC) {
  108.     return 1;
  109.     }
  110.     return 0;
  111. }
  112.  
  113.  
  114. /*
  115.  *    NextPart - get next name fromm the path
  116.  */
  117. static    char *
  118. NextPart(ppath, argv0, fullpath)
  119. char    **ppath;    /* Pointer to the next entry in the ppath */
  120. char    *argv0;        /* name of the file    */
  121. char    *fullpath;    /* path to put return info into */
  122. {
  123.     register    char    *cptr;
  124.     int    wdLen;
  125.  
  126.     /*
  127.      * Skip leading blanks and colons.    Then make sure that there's
  128.      * another entry in the ppath.
  129.      */
  130.     while (**ppath && (isspace(**ppath) || (**ppath == ':'))) {
  131.     (*ppath)++;
  132.     }
  133.     if (**ppath == '\0') {
  134.     return (NULL);
  135.     }
  136.  
  137.     /*
  138.      * Expand "." as a ppath.
  139.      */
  140.     if ((*ppath)[0] == '.' && ((*ppath)[1] == ':' || (*ppath)[1] == '\0') ) {
  141.     getwd(fullpath);
  142.     (*ppath)++;
  143.     wdLen = strlen(fullpath);
  144.     fullpath[wdLen] = '/';
  145.     strncpy(fullpath+wdLen+1, argv0, sizeof (argv0));
  146.     return (fullpath);
  147.     }
  148.     /*
  149.      * Grab the next directory name and terminate it with a slash if
  150.      * there isn't one there already.
  151.      */
  152.     for (cptr = fullpath; **ppath && !(isspace(**ppath) || (**ppath == ':'));
  153.         cptr++, (*ppath)++) {
  154.     *cptr = **ppath;
  155.     }
  156.     if (cptr[-1] != '/') {
  157.     *cptr++ = '/';
  158.     }
  159.     strncpy(cptr, argv0, strlen(argv0));
  160.     cptr[strlen(argv0)] = '\0';
  161.     return (fullpath);
  162. }
  163.